﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;

namespace hamburgerwang.common
{
    internal delegate NetworkCredential GetCredentialHandler();

    internal class HttpHelper
    {
        public event GetCredentialHandler OnGetCredential;

        public string Cookies { get; set; }

        public Encoding Encoding { get; set; }

        public HttpHelper()
        {
            this.Encoding = Encoding.UTF8;
        }

        public string Get(string url)
        {
            return Request(url, false, null,null, true);
        }

        private NetworkCredential GetCredential()
        {
            if (this.OnGetCredential != null)
            {
                return this.OnGetCredential();
            }
            else
            {
                return null;
            }
        }

        public string Post(string url, Dictionary<string, string> postData)
        {
            return Request(url, true, postData, null, true);
        }

        internal bool TryConnection(string url)
        {
            try
            {
                Request(url, false, null, null, false);
            }
            catch (System.Net.WebException ex)
            {
                if (ex.Status == WebExceptionStatus.ProtocolError && ((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.ProxyAuthenticationRequired)
                {
                    return true;
                }

            }
            return false;
        }

        private string Request(string url, bool isPost, Dictionary<string, string> data, Dictionary<string, string> headers, bool withTry)
        {
            NetworkCredential credential = null;
            if (withTry && TryConnection(url))
            {
               credential = this.GetCredential();
            }

            // Create a request using a URL that can receive a post. 
            WebRequest request = WebRequest.Create(url);
            request.UseDefaultCredentials = true;

            if (credential != null && request.Proxy != null)
            {
                request.Proxy.Credentials = credential;
            }
            
            // Set the Method property of the request to POST.
            request.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore);
            request.Method = isPost ? "POST" : "GET";
            // Set the ContentType property of the WebRequest.
            request.ContentType = "application/x-www-form-urlencoded";
            if (isPost)
            {
                // Set the ContentLength property of the WebRequest.
                StringBuilder postData = new StringBuilder();
                Dictionary<string, string>.Enumerator enumerator = data.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    if (postData.Length > 0)
                    {
                        postData.Append('&');
                    }
                    postData.Append(enumerator.Current.Key).Append('=').Append(enumerator.Current.Value);
                }
                byte[] bytes = this.Encoding.GetBytes(postData.ToString());
                request.ContentLength = bytes.Length;

                // Get the request stream.
                using (Stream dataStream = request.GetRequestStream())
                {
                    // Write the data to the request stream.
                    dataStream.Write(bytes, 0, bytes.Length);
                    // Close the Stream object.
                    dataStream.Close();
                }
            }

            // Get the response.
            using (WebResponse response = request.GetResponse())
            {
                this.Cookies = response.Headers["Set-Cookie"];
                // Get the stream containing content returned by the server.
                using (Stream dataStream = response.GetResponseStream())
                {
                    // Open the stream using a StreamReader for easy access.
                    StreamReader reader = new StreamReader(dataStream, this.Encoding);
                    // Read the content.
                    string responseFromServer = reader.ReadToEnd();
                    // Clean up the streams.
                    reader.Close();
                    dataStream.Close();
                    response.Close();
                    return responseFromServer;
                }
            }
        }
    }


    public class AspNetHelper
    {
        public static string GetSessionID(string cookies)
        {
            Match match = Regex.Match(cookies, @"ASP\.NET_SessionId\=(?<sessionid>[^;]*?)\;.*", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);
            if (match.Success)
            {
                return match.Groups["sessionid"].Value;
            }
            else
            {
                throw new ApplicationException("Cookie not found");
            }
        }

        public static string GetHtmlFieldValue(string html, string fieldName, string tagName)
        {
            string pattern = string.Format(@"\<{0}\b[^\<]*id\=""{1}""[^\<]*value=""(?<value>[^""]*?)""", tagName, fieldName);
            Match match = Regex.Match(html, pattern, RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);
            if (match.Success)
            {
                return match.Groups["value"].Value;
            }
            else
            {
                return string.Empty;
            }
        }

        public static string GetUpdatePanelFieldValue(string html, string fieldName)
        {
            string pattern = string.Format(@"{0}\|(?<value>[^\|]*?)\|", fieldName);
            Match match = Regex.Match(html, pattern, RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);
            if (match.Success)
            {
                return match.Groups["value"].Value;
            }
            else
            {
                return string.Empty;
            }
        }

        public static string GetHtmlFieldInnerHtml(string html, string fieldName, string tagName)
        {
            string pattern = string.Format(@"\<{0}\b[^\<]*id\=""{1}""[^\>]*>(?<value>.*?)?\<\/{0}\>", tagName, fieldName);
            Match match = Regex.Match(html, pattern, RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Singleline);
            if (match.Success)
            {
                return match.Groups["value"].Value.Replace("&nbsp;", "");
            }
            else
            {
                return string.Empty;
            }
        }

        public static string[] GetHtmlFieldInnerHtml(string html, string tagName)
        {
            string pattern = string.Format(@"\<{0}\b[^\>]*>(?<value>.*?)?\<\/{0}\>", tagName);
            Match match = Regex.Match(html, pattern, RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Singleline);
            if (match.Success)
            {
                List<string> list = new List<string>();
                do
                {
                    list.Add(match.Groups["value"].Value.Replace("&nbsp;", ""));
                    match = match.NextMatch();
                } 
                while (match.Success);
                return list.ToArray();
            }
            else
            {
                return new string[0];
            }
        }
    }
}
